現在使用者已經可以登入系統了,但是使用者的姓名、員工編號等相關資料該如何取得呢?當然我們可以每次有需要時都去資料庫查詢,或是自行存放到Session裡,只不過做為一個先進的雲端系統,維持系統在stateless狀態是一件重要的事情。在ASP.NET中其實可以透過User.Identity的方式來取得目前登入的使用者識別資料,但裡頭能抓到的只有login id (雖然叫User.Identity.Name,但存放的卻是login id 囧),所以我們可以利用擴充方法來讓Identity可以取得其他的使用者識別資料。
首先先修改UserStore,讓它實作IUserClaimStore介面。
public class UserStore : IUserStore<ApplicationUser>,
IUserPasswordStore<ApplicationUser>,
IUserRoleStore<ApplicationUser>,
IUserClaimStore<ApplicationUser>
{
public const string EmpNo = "http://schemas.acer.com/ws/2014/01/identity/claims/empno";
public Task<IList<Claim>> GetClaimsAsync(ApplicationUser user)
{
List<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Sid, user.Id, XmlSchemaString));
claims.Add(new Claim(ClaimTypes.GivenName, user.Name, XmlSchemaString));
claims.Add(new Claim(EmpNo, user.EmpNo, XmlSchemaString));
return Task.FromResult<IList<Claim>>(claims);
}
public Task AddClaimAsync(ApplicationUser user, Claim claim)
{
throw new NotImplementedException();
}
public Task RemoveClaimAsync(ApplicationUser user, Claim claim)
{
throw new NotImplementedException();
}
}
UserManager會在CreateIdentity時檢查UserStore是否有實作IUserClaimStore,並且呼叫GetClaimsAsync來將自訂的Claim加入Identity。因此我們再增加一個IIIdentity介面的擴充方法,便可以從Identity中取得這些額外的資訊。
public static class IdentityExtensions
{
public static string GetUserName(this IIdentity identity)
{
return GetClaimsValue(identity, ClaimTypes.GivenName);
}
public static string GetEmpNo(this IIdentity identity)
{
return GetClaimsValue(identity, UserStore.EmpNo);
}
private static string FindFirstValue(ClaimsIdentity identity, string claimType)
{
Claim first = identity.FindFirst(claimType);
if (first != null)
{
return first.Value;
}
else
{
return null;
}
}
private static string GetClaimsValue(IIdentity identity, string claimType)
{
if (identity == null)
{
throw new ArgumentNullException("identity");
}
ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
if (claimsIdentity != null)
{
return FindFirstValue(claimsIdentity, claimType);
}
else
{
return null;
}
}
}
之後就能透User.Identity.GetUserName()的方式來取得使用者名稱。